﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Action = Styx.TreeSharp.Action;

namespace TuanHA_Paladin
{
    public partial class Classname : CombatRoutine
    {
        //[DllImport("user32.dll")]
        //private static extern IntPtr GetForegroundWindow();

        //[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        //private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

        //private string GetActiveWindowTitle()
        //{
        //    const int nChars = 256;
        //    IntPtr handle = IntPtr.Zero;
        //    StringBuilder Buff = new StringBuilder(nChars);
        //    handle = GetForegroundWindow();

        //    if (GetWindowText(handle, Buff, nChars) > 0)
        //    {
        //        return Buff.ToString();
        //    }
        //    return null;
        //}

        #region Delegates

        public delegate WoWPoint LocationRetriverDelegate(object context);

        #endregion

        #region Basic Functions

        public override bool WantButton
        {
            get { return true; }
        }

        public override WoWClass Class
        {
            get { return WoWClass.Paladin; }
        }

        public override string Name
        {
            get { return "TuanHA Paladin The Ultimate Experience [Special Edition] rev. 290"; }
        }

        public override Composite RestBehavior
        {
            get { return RestRotation(); }
        }

        public override Composite PreCombatBuffBehavior
        {
            get { return MainRotation(); }
        }

        //public override Composite PullBuffBehavior
        //{
        //    get { return MainRotation(); }
        //}

        //public override Composite PullBehavior
        //{
        //    get { return MainRotation(); }
        //}

        //public override Composite CombatBuffBehavior
        //{
        //    get { return MainRotation(); }
        //}

        public override Composite CombatBehavior
        {
            get { return MainRotation(); }
        }

        //public override Composite HealBehavior
        //{
        //    get { return MainRotation(); }
        //}

        //public override Composite MoveToTargetBehavior
        //{
        //    get { return CreateMoveToLosBehavior(); }
        //}

        public static LocalPlayer Me
        {
            get { return StyxWoW.Me; }
        }

        public override void Initialize()
        {
            Logging.Write("");
            Logging.Write("Hello " + Me.Race + " " + Me.Class);
            Logging.Write("Thank you for using TuanHA Paladin");
            Logging.Write("");

            //Disable for speed
            Lua.Events.AttachEvent("GROUP_ROSTER_UPDATE", UpdateGroupChangeEvent);
            Lua.Events.AttachEvent("ACTIVE_TALENT_GROUP_CHANGED", UpdateStatusEvent);
            Lua.Events.AttachEvent("PLAYER_TALENT_UPDATE", UpdateMyTalentEvent);
            Lua.Events.AttachEvent("GLYPH_ADDED", UpdateMyGlyphEvent);
            //Lua.Events.AttachEvent("WORLD_MAP_NAME_UPDATE", UpdateCurrentMapEvent);

            //BotEvents.Player.OnMapChanged += UpdateCurrentMapEvent;
            BotEvents.OnBotStarted += OnBotStartedEvent;

            //Set Camera angle so you never have problem with it
            //console cameraSmoothTrackingStyle 0 (credit by alxaw - member of CLU dev team) 
            //Lua.DoString("RunMacroText(\"/console cameraSmoothTrackingStyle 1\")");

            THSettings.Instance.UpdateStatus = true;
        }

        public override void OnButtonPress()
        {
            var gui = new THForm();
            gui.ShowDialog();
        }

        #endregion

        #region Function After this Region Order Alphabetically

        #endregion

        #region GetUnits

        public List<WoWUnit> FarFriendlyPlayers = new List<WoWUnit>();
        public List<WoWUnit> FarFriendlyUnits = new List<WoWUnit>();
        public List<WoWPlayer> NearbyFriendlyPlayers = new List<WoWPlayer>();
        public List<WoWUnit> NearbyFriendlyUnits = new List<WoWUnit>();
        public List<WoWPlayer> NearbyUnFriendlyPlayers = new List<WoWPlayer>();
        public List<WoWUnit> NearbyUnFriendlyUnits = new List<WoWUnit>();

        //public List<WoWUnit> FarUnFriendlyPlayers = new List<WoWUnit>();//Don't use in this CC
        //public List<WoWUnit> FarUnFriendlyUnits = new List<WoWUnit>();

        public void GetUnits()
        {
            NearbyFriendlyPlayers.Clear();
            NearbyUnFriendlyPlayers.Clear();
            NearbyFriendlyUnits.Clear();
            NearbyUnFriendlyUnits.Clear();
            FarFriendlyPlayers.Clear();
            FarFriendlyUnits.Clear();

            NearbyFriendlyUnits.Add(Me);
            NearbyFriendlyPlayers.Add(Me);
            FarFriendlyUnits.Add(Me);
            FarFriendlyPlayers.Add(Me);

            IEnumerable<WoWUnit> units =
                ObjectManager.GetObjectsOfType<WoWUnit>(true, false).Where(p => ValidUnit(p) && p.Distance < 60);

            foreach (WoWUnit unit in units)
            {
                //using (StyxWoW.Memory.AcquireFrame())
                {
                    if (IsMyPartyRaidMember(unit))
                    {
                        FarFriendlyUnits.Add(unit);

                        var player = unit as WoWPlayer;
                        if (player != null)
                        {
                            FarFriendlyPlayers.Add(unit);
                        }

                        if (GetMinDistance(unit) < 40)
                        {
                            NearbyFriendlyUnits.Add(unit);

                            if (player != null)
                            {
                                NearbyFriendlyPlayers.Add(player);
                            }
                        }
                    }
                    else if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
                    {
                        if (GetMaxDistance(unit) > 40)
                        {
                            continue;
                        }
                        NearbyUnFriendlyUnits.Add(unit);

                        var player = unit as WoWPlayer;
                        if (player != null)
                        {
                            NearbyUnFriendlyPlayers.Add(player);
                        }
                    }
                    else if (IsEnemy(unit))
                    {
                        if (GetMaxDistance(unit) > 40)
                        {
                            continue;
                        }
                        NearbyUnFriendlyUnits.Add(unit);

                        var player = unit as WoWPlayer;
                        if (player != null)
                        {
                            NearbyUnFriendlyPlayers.Add(player);
                        }
                    }
                }
            }
        }

        #endregion

        #region GetUnitHeal

        public WoWUnit UnitHeal;

        public void GetUnitHeal()
        {
            UnitHeal = null;
            //Tsulong override
            if (Me.GotTarget && Me.CurrentTarget.Entry == 62442 &&
                (!Me.CurrentTarget.Attackable || Me.CurrentTarget.IsFriendly))
            {
                if (UnitHeal == null || (UnitHeal != null && UnitHeal.HealthPercent <= THSettings.Instance.SUrgentHeal))
                {
                    UnitHeal = Me.CurrentTarget;
                    return;
                }
            }

            //Tsulong override
            if (Me.FocusedUnit != null && Me.FocusedUnit.Entry == 62442 &&
                (!Me.FocusedUnit.Attackable || Me.FocusedUnit.IsFriendly))
            {
                if (UnitHeal == null || (UnitHeal != null && UnitHeal.HealthPercent <= THSettings.Instance.SUrgentHeal))
                {
                    UnitHeal = Me.FocusedUnit;
                    return;
                }
            }

            if (Healable(Me.CurrentTarget) && Me.CurrentTarget != UnitHealFull &&
                Me.CurrentTarget.HealthPercent < THSettings.Instance.SDoNotHealAbove &&
                (Me.CurrentTarget.IsPlayer || Me.CurrentTarget.IsPet))
            {
                UnitHeal = Me.CurrentTarget;
                return;
            }

            if (Me.HealthPercent < THSettings.Instance.SPriorityHeal &&
                Me != UnitHealFull && !Me.CurrentMap.IsArena)
            {
                UnitHeal = Me;
                return;
            }

            if (Me.FocusedUnit != null &&
                (Healable(Me.FocusedUnit) &&
                 Me.FocusedUnit != UnitHealFull &&
                 Me.FocusedUnit.HealthPercent < THSettings.Instance.SDoNotHealAbove &&
                 (Me.FocusedUnit.IsPlayer || Me.FocusedUnit.IsPet) &&
                 !Me.CurrentMap.IsArena))
            {
                UnitHeal = Me.FocusedUnit;
            }

            else
            {
                //using (StyxWoW.Memory.AcquireFrame())
                {
                    UnitHeal = (from unit in NearbyFriendlyUnits
                                where !Blacklist.Contains(unit.Guid, BlacklistFlags.All)
                                orderby unit.HealthPercent ascending
                                //where unit != UnitHealFull
                                where unit.IsPlayer || Me.CurrentMap.IsArena && unit.IsPet
                                where Healable(unit)
                                select unit).FirstOrDefault();
                }
            }
        }

        #endregion

        #region GetUnitAttack

        public WoWUnit UnitAttack;
        public WoWUnit UnitAttackPet;

        public void GetUnitAttack()
        {
            UnitAttack = null;
            UnitAttackPet = null;

            //if (THSettings.Instance.SAutoTarget)
            //{
            //using (StyxWoW.Memory.AcquireFrame())
            {
                if (!SpellManager.HasSpell("Holy Insight"))
                {
                    UnitAttack = (from unit in NearbyUnFriendlyUnits
                                  //Only search Target if in instance
                                  //where Me.IsInInstance
                                  orderby unit.Distance ascending
                                  //attack any unit if not in dungeon/raid
                                  where unit.Combat
                                  //where unit.GotTarget
                                  //only attack unit not tagged
                                  where
                                      unit.IsTargetingMeOrPet ||
                                      unit.IsTargetingMyPartyMember ||
                                      unit.IsTargetingMyRaidMember ||
                                      unit.IsPlayer && (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)
                                  where AttackableValid(unit)
                                  select unit).FirstOrDefault();
                }
                else
                {
                    UnitAttack = (from unit in NearbyUnFriendlyUnits
                                  //Only search Target if in instance
                                  //where Me.IsInInstance
                                  orderby unit.HealthPercent ascending
                                  //attack any unit if not in dungeon/raid
                                  where unit.Combat
                                  //where unit.GotTarget
                                  //only attack unit not tagged
                                  where
                                      unit.IsTargetingMeOrPet ||
                                      unit.IsTargetingMyPartyMember ||
                                      unit.IsTargetingMyRaidMember ||
                                      unit.IsPlayer && (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)
                                  where AttackableValid(unit)
                                  select unit).FirstOrDefault();
                }
                //if it pet, try to find a player
                if (UnitAttack != null && !UnitAttack.IsPlayer && !Me.CurrentMap.IsRaid && !Me.CurrentMap.IsDungeon)
                {
                    UnitAttackPet = UnitAttack;
                    UnitAttack = (from unit in NearbyUnFriendlyPlayers
                                  orderby unit.Distance ascending
                                  where unit.Combat && unit.IsTargetingMeOrPet || Me.CurrentMap.IsBattleground
                                  where AttackableValid(unit)
                                  select unit).FirstOrDefault();

                    //can't find a player, kill the pet
                    if (UnitAttack == null && UnitAttackPet != null)
                    {
                        UnitAttack = UnitAttackPet;
                    }
                }
            }
            //}
        }

        #endregion

        #region GroupMembers

        internal static IEnumerable<WoWPartyMember> GroupMembers
        {
            get { return !Me.GroupInfo.IsInRaid ? Me.GroupInfo.PartyMembers : Me.GroupInfo.RaidMembers; }
        }

        #endregion

        #region Hold

        public static string MyCastingSpells =
            "[Divine Light] [Flash of Light] [Holy Light] [Divine Plea] [Holy Radiance] [Holy Shock] [Light of Dawn] [Word of Glory] [Denounce] [Repentance]";

        public Composite Hold()
        {
            return
                new Decorator(
                    ret =>
                    Me.HasAura("Drink") || Me.HasAura("Food") ||
                    Me.IsCasting && MyCastingSpells.Contains(Me.CastingSpell.Name) ||
                    Me.IsChanneling ||
                    !Me.IsAlive,
                    new Action(delegate { return RunStatus.Success; })
                    );
        }

        #endregion

        #region Pulse

        public DateTime LastSwitch;
        public DateTime BurstLast;

        public override void Pulse()
        {
            if (THSettings.Instance.UpdateStatus)
            {
                UpdateStatus();
            }
            else
            {
                ObjectManager.Update();
                GetUnits();
                GetUnitHeal();
                StopCastingCheck();
                GetUnitAttack();

                //Pause
                if (THSettings.Instance.SUsePauseKey && THSettings.Instance.SPauseKey != 0)
                {
                    //AoE Mode
                    if (GetAsyncKeyState(Keys.LControlKey) < 0 &&
                        GetAsyncKeyState(IndexToKeys(THSettings.Instance.SPauseKey)) < 0 &&
                        LastSwitch.AddSeconds(1) < DateTime.Now) // && GetActiveWindowTitle() == "World of Warcraft")
                    {
                        if (THSettings.Instance.SPause)
                        {
                            THSettings.Instance.SPause = false;
                            LastSwitch = DateTime.Now;
                            Logging.Write("Pause Mode is OFF, Ctrl + " +
                                          IndexToKeys(THSettings.Instance.SPauseKey) +
                                          " to Override bot action.");
                            Lua.DoString("RunMacroText(\"/script msg='Pause Mode OFF' print(msg)\")");
                        }
                        else
                        {
                            THSettings.Instance.SPause = true;
                            LastSwitch = DateTime.Now;
                            Logging.Write("Pause Mode is ON, Ctrl + " +
                                          IndexToKeys(THSettings.Instance.SPauseKey) +
                                          " to resume bot action.");
                            Lua.DoString("RunMacroText(\"/script msg='Pause Mode ON' print(msg)\")");
                        }
                    }
                }

                //AoE
                if (THSettings.Instance.SUseAoeKey && THSettings.Instance.SAOEKey != 0)
                {
                    //AoE Mode
                    if (GetAsyncKeyState(Keys.LControlKey) < 0 &&
                        GetAsyncKeyState(IndexToKeys(THSettings.Instance.SAOEKey)) < 0 &&
                        LastSwitch.AddSeconds(1) < DateTime.Now) // && GetActiveWindowTitle() == "World of Warcraft")
                    {
                        if (THSettings.Instance.SAOE)
                        {
                            THSettings.Instance.SAOE = false;
                            LastSwitch = DateTime.Now;
                            Logging.Write("AoE Mode is OFF, Ctrl + " +
                                          IndexToKeys(THSettings.Instance.SAOEKey) +
                                          " to Turn AoE Mode ON.");
                            Lua.DoString("RunMacroText(\"/script msg='AoE Mode OFF' print(msg)\")");
                        }
                        else
                        {
                            THSettings.Instance.SAOE = true;
                            LastSwitch = DateTime.Now;
                            Logging.Write("AoE Mode is ON, Ctrl + " +
                                          IndexToKeys(THSettings.Instance.SAOEKey) +
                                          " to Turn AoE Mode OFF.");
                            Lua.DoString("RunMacroText(\"/script msg='AoE Mode ON' print(msg)\")");
                        }
                    }
                }

                //Auto Disactivate Burst after a Timer or Me get CC
                if (THSettings.Instance.SBurst && (BurstLast < DateTime.Now || DebuffCC(Me) > _myLatency))
                {
                    THSettings.Instance.SBurst = false;
                    BurstLast = DateTime.Now;
                    Logging.Write("Burst Mode is OFF");
                    Lua.DoString("RunMacroText(\"/script msg='Burst Mode OFF' print(msg)\")");
                }

                //Burst on Cooldown
                if (THSettings.Instance.SBurstKey == 1 && THSettings.Instance.SBurst == false &&
                    DebuffCC(Me) <= _myLatency)
                {
                    BurstLast = DateTime.Now.AddHours(1);
                    Logging.Write("Burst Mode Activated On Cooldown");
                    THSettings.Instance.SBurst = true;
                }

                //Burst on Bloodlust
                if (THSettings.Instance.SBurstKey == 2 && THSettings.Instance.SBurst == false &&
                    (Me.HasAura("Bloodlust") || Me.HasAura("Heroism") || Me.HasAura("Time Warp") ||
                     Me.HasAura("Ancient Hysteria")) && DebuffCC(Me) <= _myLatency)
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated On Bloodlust/Heroism/Time Warp/Ancient Hysteria");
                    THSettings.Instance.SBurst = true;
                }

                //Burst On Lose Control
                if (THSettings.Instance.SBurstKey == 3 && THSettings.Instance.SBurst == false &&
                    DebuffCC(Me) > 3000)
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated on Lose Control");
                    THSettings.Instance.SBurst = true;
                }

                //Burst On My Health Below
                if (THSettings.Instance.SBurstKey == 4 && THSettings.Instance.SBurst == false &&
                    Me.HealthPercent < THSettings.Instance.SBurstHP && DebuffCC(Me) <= _myLatency)
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated on My Health Low");
                    THSettings.Instance.SBurst = true;
                }

                //Burst On Friend Health Below
                if (THSettings.Instance.SBurstKey == 5 && THSettings.Instance.SBurst == false &&
                    UnitHeal != null && UnitHeal.IsValid && UnitHeal.IsAlive && !UnitHeal.IsPet &&
                    UnitHeal.HealthPercent < THSettings.Instance.SBurstHP &&
                    DebuffCC(Me) <= _myLatency)
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated on Friend Health Low");
                    THSettings.Instance.SBurst = true;
                }

                //Burst On Enemy Health Below
                if (THSettings.Instance.SBurstKey == 6 && THSettings.Instance.SBurst == false &&
                    Me.CurrentTarget != null && Me.CurrentTarget.IsValid &&
                    ValidUnit(Me.CurrentTarget) &&
                    IsEnemy(Me.CurrentTarget) &&
                    !Me.CurrentTarget.IsPet &&
                    Me.HealthPercent > THSettings.Instance.SUrgentHeal &&
                    Me.CurrentTarget.HealthPercent < THSettings.Instance.SBurstHP && DebuffCC(Me) <= _myLatency)
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated on Enemy Health Low");
                    THSettings.Instance.SBurst = true;
                }

                //Burst On My Mana Below
                if (THSettings.Instance.SBurstKey == 7 && THSettings.Instance.SBurst == false &&
                    Me.ManaPercent < THSettings.Instance.SBurstHP && DebuffCC(Me) <= _myLatency)
                {
                    BurstLast = DateTime.Now.AddSeconds(15);
                    Logging.Write("Burst Mode Activated on My Mana Low");
                    THSettings.Instance.SBurst = true;
                }

                //Burst by key press
                if (THSettings.Instance.SBurstKey > 7)
                {
                    //Burst Mode
                    if (GetAsyncKeyState(Keys.LControlKey) < 0 &&
                        GetAsyncKeyState(IndexToKeys(THSettings.Instance.SBurstKey - 7)) < 0 &&
                        LastSwitch.AddSeconds(1) < DateTime.Now) // && GetActiveWindowTitle() == "World of Warcraft")
                    {
                        if (THSettings.Instance.SBurst || DebuffCC(Me) > _myLatency)
                        {
                            THSettings.Instance.SBurst = false;
                            LastSwitch = DateTime.Now;
                            Logging.Write("Burst Mode is OFF, Ctrl + " +
                                          IndexToKeys(THSettings.Instance.SBurstKey - 7) +
                                          " to Turn Burst Mode ON.");
                            Lua.DoString("RunMacroText(\"/script msg='Burst Mode OFF' print(msg)\")");
                        }
                        else if (DebuffCC(Me) <= _myLatency)
                        {
                            THSettings.Instance.SBurst = true;
                            LastSwitch = DateTime.Now;
                            BurstLast = DateTime.Now.AddSeconds(15);
                            Logging.Write("Burst Mode is ON, Ctrl + " +
                                          IndexToKeys(THSettings.Instance.SBurstKey - 7) +
                                          " to Turn Burst Mode OFF.");
                            Lua.DoString("RunMacroText(\"/script msg='Burst Mode ON' print(msg)\")");
                        }
                    }
                }
            }
        }

        #endregion

        #region GetPhysicDPSTarget

        //public WoWUnit PhysicDPSTarget;

        //private bool GetPhysicDPSTarget(WoWObject target)
        //{
        //    //using (StyxWoW.Memory.AcquireFrame())
        //    {
        //        PhysicDPSTarget = null;
        //        if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
        //        {
        //            PhysicDPSTarget = (from unit in NearbyUnFriendlyPlayers
        //                               where unit.CurrentTarget == target
        //                               where
        //                                   TalentSort(unit) == 2 && unit.Location.Distance(target.Location) < 40 ||
        //                                   TalentSort(unit) == 1 && unit.Location.Distance(target.Location) < 6
        //                               where DebuffCC(unit) <= 0
        //                               select unit).FirstOrDefault();
        //        }
        //        else
        //        {
        //            PhysicDPSTarget = (from unit in NearbyUnFriendlyUnits
        //                               where unit.CurrentTarget == target
        //                               where unit.Location.Distance(target.Location) < 6
        //                               //Make sure it melee
        //                               where DebuffCC(unit) <= 0
        //                               select unit).FirstOrDefault();
        //        }
        //        return PhysicDPSTarget != null;
        //    }
        //}

        #endregion

        #region MainRotation

        //public bool HelloFriend = false;
        public bool IsConstantFace;
        public bool IsOverrideModeOn;
        public WoWUnit MyLastTarget;
        public readonly DateTime Now = DateTime.Now;
        //public Stopwatch PendingSpellStopWatch = new Stopwatch();
        public DateTime TickMilisecond;
        public DateTime TickMilisecondTotal;
        public WoWUnit UnitHealFull;
        public DateTime DoNotMove;

        public Composite MainRotation()
        {
            return new PrioritySelector(
                Hold(),
                new Decorator(
                    ret => THSettings.Instance.SPause,
                    new Action(delegate { return RunStatus.Success; })),
                new Decorator(
                    ret =>
                    THSettings.Instance.UpdateStatus,
                    new Action(delegate
                        {
                            //Logging.Write("Need Update Status first");
                            //UpdateStatus();
                            return RunStatus.Success;
                        })),
                new Decorator(
                    ret => (Me.HasAura("Resurrection Sickness") ||
                            !StyxWoW.IsInWorld ||
                            !Me.IsValid),
                    new Action(delegate
                        {
                            THSettings.Instance.UpdateStatus = true;
                            Logging.Write(LogLevel.Diagnostic,
                                          "Resurrection Sickness or not in WoW, Skip Main Rotation.");
                            return RunStatus.Success;
                        })),
                //Trying to stop bot movement while casting
                new Decorator(
                    ret =>
                    TreeRoot.Current.Name != "LazyRaider" &&
                    TreeRoot.Current.Name != "Raid Bot" &&
                    TreeRoot.Current.Name != "Combat Bot" &&
                    (Me.IsCasting || DoNotMove > DateTime.Now),
                    new Action(delegate { return RunStatus.Success; })
                    ),
                new Action(delegate
                    {
                        if (Me.IsInInstance && EventHandlers.CombatLogAttached)
                        {
                            EventHandlers.DetachCombatLogEvent();
                            //Logging.Write(LogLevel.Diagnostic, "DetachCombatLogEvent");
                        }

                        if (!Me.IsInInstance && !EventHandlers.CombatLogAttached)
                        {
                            EventHandlers.AttachCombatLogEvent();
                            //Logging.Write(LogLevel.Diagnostic, "AttachCombatLogEvent");
                        }

                        if (!IsOverrideModeOn &&
                            //Do not stop movement in LazyRaider if SMoveToTarget enabled
                            //TreeRoot.Current.Name != "LazyRaider" &&
                            (GetAsyncKeyState(Keys.LButton) < 0 &&
                             GetAsyncKeyState(Keys.RButton) < 0) ||
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.SStrafleLeft)) < 0 &&
                            IndexToKeys(THSettings.Instance.SStrafleLeft) != Keys.None ||
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.SForward)) < 0 &&
                            IndexToKeys(THSettings.Instance.SForward) != Keys.None ||
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.SStrafleRight)) < 0 &&
                            IndexToKeys(THSettings.Instance.SStrafleRight) != Keys.None ||
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.STurnLeft)) < 0 &&
                            IndexToKeys(THSettings.Instance.STurnLeft) != Keys.None ||
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.SBackward)) < 0 &&
                            IndexToKeys(THSettings.Instance.SBackward) != Keys.None ||
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.STurnRight)) < 0 &&
                            IndexToKeys(THSettings.Instance.STurnRight) != Keys.None)
                        {
                            //Logging.Write(LogLevel.Diagnostic, "Override mode on. Stop all bot movement");
                            IsOverrideModeOn = true;
                        }

                        if (IsOverrideModeOn &&
                            //Do not stop movement in LazyRaider if SMoveToTarget enabled
                            //TreeRoot.Current.Name != "LazyRaider" &&
                            (GetAsyncKeyState(Keys.LButton) >= 0 ||
                             GetAsyncKeyState(Keys.RButton) >= 0) &&
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.SStrafleLeft)) >= 0 &&
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.SForward)) >= 0 &&
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.SStrafleRight)) >= 0 &&
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.STurnLeft)) >= 0 &&
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.SBackward)) >= 0 &&
                            GetAsyncKeyState(IndexToKeys(THSettings.Instance.STurnRight)) >= 0)
                        {
                            //Logging.Write(LogLevel.Diagnostic, "Override mode off. Bot movement resume");
                            IsOverrideModeOn = false;
                        }

                        //if (GetAsyncKeyState(Keys.F9) != 0)
                        //{
                        //    Logging.Write("MainRotation take " +
                        //                  Math.Round((DateTime.Now -
                        //                              TickMilisecondTotal).TotalMilliseconds) +
                        //                  " ms");
                        //    TickMilisecondTotal = DateTime.Now;
                        //}

                        //GetAllMyAuras
                        //if (GetAsyncKeyState(Keys.F10) < 0)
                        //{
                        //    DumpAuras();
                        //}

                        //GroupMember
                        //if (GetAsyncKeyState(Keys.F11) < 0)
                        //{
                        //    Logging.Write("List of GroupNumber");
                        //    foreach (var woWPartyMember in GroupMembers)
                        //    {
                        //        if (woWPartyMember.ToPlayer() != null)
                        //        {
                        //            Logging.Write(woWPartyMember.ToPlayer().Name + " in Group " +
                        //                          woWPartyMember.GroupNumber);
                        //        }
                        //    }
                        //}

                        //WriteDebugEnalbe
                        if (GetAsyncKeyState(Keys.F12) < 0)
                        {
                            if(!WriteDebugEnable)
                            {
                                WriteDebugEnable = true;
                            }
                            else
                            {
                                WriteDebugEnable = false;
                            }
                        }


                        //Get target back after a fear
                        if (Me.CurrentTarget != null && MyLastTarget != Me.CurrentTarget)
                        {
                            MyLastTarget = Me.CurrentTarget;
                        }

                        //Clear Target if dead and still in combat
                        if (Me.CurrentTarget != null && !Me.CurrentTarget.IsAlive && Me.Combat)
                        {
                            Lua.DoString("RunMacroText(\"/cleartarget\")");
                        }

                        //Clear Target if walk away from friendly
                        if (Me.CurrentTarget != null && !Me.CurrentTarget.IsPlayer &&
                            Me.CurrentTarget.IsFriendly &&
                            Me.CurrentTarget.IsSafelyBehind(Me))
                        {
                            Lua.DoString("RunMacroText(\"/cleartarget\")");
                        }


                        //Death Knight Dark Simulacrum
                        //if (Me.HasAura("Dark Simulacrum"))
                        //{
                        //    CastSpell("Seal of Insight", Me);
                        //    return RunStatus.Success;
                        //}

                        return RunStatus.Failure;
                    }
                    ),
                SetAutoAttack(),
                UseRacial(),
                UseTrinket(),
                UseProfession(),
                new Decorator(
                    ret =>
                    SpellManager.HasSpell("Avenger's Shield"),
                    ProtectionRotation()
                    ),
                new Decorator(
                    ret =>
                    SpellManager.HasSpell("Holy Insight"),
                    HolyRotation()
                    ),
                new Decorator(
                    ret =>
                    !SpellManager.HasSpell("Avenger's Shield") &&
                    !SpellManager.HasSpell("Holy Insight"),
                    RetributionRotation()
                    )
                );
        }

        #endregion
    }
}